package com.common.service.departmentjob.impl;

import com.common.converter.DepartmentConverter;
import com.common.entity.department.DepartmentEntity;
import com.common.entity.department.QDepartmentEntity;
import com.common.global.BizException;
import com.common.global.BizServiceEnum;
import com.common.global.CommonEnum;
import com.common.query.QueryConditionVo;
import com.common.repository.departmentjob.DepartmentRepository;
import com.common.requestvo.departmentjob.DepartmentReqVo;
import com.common.service.departmentjob.DepartmentService;
import com.common.vo.departmentjob.DepartmentVo;
import com.querydsl.core.QueryResults;
import com.querydsl.jpa.impl.JPAQuery;
import com.querydsl.jpa.impl.JPAQueryFactory;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;

import javax.transaction.Transactional;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author johnny
 * @create 2021-05-14 9:04 下午
 **/
@Service
@Slf4j
@Transactional(rollbackOn = Exception.class)
public class DepartmentServiceImpl implements DepartmentService {
    private final JPAQueryFactory queryFactory;

    private final DepartmentRepository departmentRepository;

    public DepartmentServiceImpl(JPAQueryFactory queryFactory, DepartmentRepository departmentRepository) {
        this.queryFactory = queryFactory;
        this.departmentRepository = departmentRepository;
    }

    @Override
    public Page<DepartmentVo> listByCondition(DepartmentReqVo departmentReqVo, Pageable pageable) {
        List<DepartmentVo> list = new ArrayList<>();
        QDepartmentEntity qDepartmentEntity = QDepartmentEntity.departmentEntity;

        JPAQuery<DepartmentEntity> jpaQuery = queryFactory.select(qDepartmentEntity)
                .from(qDepartmentEntity)
                .offset(pageable.getPageNumber() * pageable.getPageSize())
                .limit(pageable.getPageSize());

        fillCondition(jpaQuery, departmentReqVo);
        QueryResults<DepartmentEntity> queryResults = jpaQuery.fetchResults();

        queryResults.getResults().forEach(departmentEntity -> {
            DepartmentVo departmentVo = DepartmentConverter.INSTANCE.domain2vo(departmentEntity);
            list.add(departmentVo);
        });
        return new PageImpl<>(list, pageable, queryResults.getTotal());
    }

    @Override
    public void add(DepartmentReqVo departmentReqVo) {
        departmentReqVo.setId(null);
        Long count = departmentRepository.countByDepartmentName(departmentReqVo.getDepartmentName());
        if (count == 0) {
            DepartmentEntity departmentEntity = DepartmentConverter.INSTANCE.vo2domain(departmentReqVo);
            departmentRepository.save(departmentEntity);
        }
    }

    @Override
    public void edit(DepartmentReqVo departmentReqVo) {
        if (departmentReqVo.getId() != null && departmentReqVo.getId() != 0L) {
            if (departmentRepository.existsById(departmentReqVo.getId())) {
                DepartmentEntity departmentEntity = DepartmentConverter.INSTANCE.vo2domain(departmentReqVo);
                departmentRepository.save(departmentEntity);
            } else {
                throw new BizException(CommonEnum.ID_NOT_FIND_ENTITY);
            }
        } else {
            throw new BizException(CommonEnum.ID_NOT_NULL);
        }
    }

    @Override
    public void delete(Long id) {
        if (departmentRepository.existsById(id)) {
            departmentRepository.deleteById(id);
        } else {
            throw new BizException(CommonEnum.ID_NOT_FIND_ENTITY);
        }
    }

    @Override
    public DepartmentVo checkDepartmentExist(Long departmentId) throws BizException {
        DepartmentEntity departmentEntity = departmentRepository.findById(departmentId).orElse(null);
        if (departmentEntity != null) {
            return DepartmentConverter.INSTANCE.domain2vo(departmentEntity);
        } else {
            throw new BizException(BizServiceEnum.DEPARTMENT_NOT_FIND);
        }
    }

    @Override
    public List<DepartmentVo> findAllDepartment() {
        return departmentRepository.findAll().stream().map(DepartmentConverter.INSTANCE::domain2vo)
                .collect(Collectors.toList());
    }


    @Override
    public void fillCondition(JPAQuery<DepartmentEntity> jpaQuery, QueryConditionVo queryConditionVo) {
        QDepartmentEntity qDepartmentEntity = QDepartmentEntity.departmentEntity;
        DepartmentReqVo departmentReqVo = (DepartmentReqVo) queryConditionVo;
        if (StringUtils.isNotEmpty(departmentReqVo.getDepartmentName())) {
            jpaQuery.where(qDepartmentEntity.departmentName.like("%" + departmentReqVo.getDepartmentName() + "%"));
        }
    }
}